package me.zhengjie.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.dao.DispositionDao;
import me.zhengjie.dao.StoreLocalDao;
import me.zhengjie.dao.StoreOutsideDao;
import me.zhengjie.dao.dto.StoreOutsideQueryCriteria;
import me.zhengjie.enums.ConstantStatus;
import me.zhengjie.enums.InboundStatusEnum;
import me.zhengjie.mapper.StoreOutsideMapper;
import me.zhengjie.server.DispositionService;
import me.zhengjie.server.StoreOutsideService;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageResult;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.vo.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author xinglin.lu
 * @description 针对表【iws_store_outside】的数据库操作Service实现
 * @createDate 2025-06-13 17:05:47
 */
@Service
public class StoreOutsideServiceImpl extends ServiceImpl<StoreOutsideMapper, StoreOutsideDao>
        implements StoreOutsideService {

    @Resource
    private StoreOutsideMapper storeOutsideMapper;

    @Resource
    private DispositionService dispositionService;

    @Override
    public PageResult<StoreOutsideDao> queryAll(StoreOutsideQueryCriteria criteria, Page<Object> page) {
        return PageUtil.toPage(storeOutsideMapper.findAll(criteria, page));
    }

    @Override
    public List<StoreOutsideDao> queryAll(StoreOutsideQueryCriteria criteria) {
        return storeOutsideMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(StoreOutsideDao resources) {
        storeOutsideMapper.insert(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(StoreOutsideDao resources) {
        StoreOutsideDao storeOutside = getById(resources.getId());
        storeOutside.copy(resources);
        storeOutsideMapper.updateById(storeOutside);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<String> ids) {
        storeOutsideMapper.deleteBatchIds(ids);
    }

    /**
     * 根据楼层和货物类型查询可用储位
     *
     * @param floor    楼层
     * @param workIp   工作站IP
     * @param goodType 货物类型
     * @return 可用储位ID列表
     */
    public List<String> findAvailableStoreId(String name, String floor, String workIp, String goodType) {
        return storeOutsideMapper.findAvailableStoreId(name, floor, workIp, goodType);
    }

    /**
     * 根据楼层和货物类型查询可用储位
     *
     * @param floor    楼层
     * @param goodType 货物类型
     * @return 可用储位ID列表
     */
    public List<String> findAvailableStoreId(String floor, String goodType) {
        return storeOutsideMapper.findAvailableStoreIdByGoodType(floor, goodType);
    }


    public boolean updateDataList(List<String> ids, StoreOutsideDao storeOutsideDao){
        LambdaUpdateWrapper<StoreOutsideDao> localWrapper = new LambdaUpdateWrapper<>();
        localWrapper.in(StoreOutsideDao::getId, ids);
        this.setUpdateWrapper(storeOutsideDao, localWrapper);
        return this.update(localWrapper);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateData(StoreOutsideDao storeOutsideDao) {
        LambdaUpdateWrapper<StoreOutsideDao> wrapper = new LambdaUpdateWrapper<>();
        if (storeOutsideDao.getId() != null) {
            wrapper.eq(StoreOutsideDao::getId, storeOutsideDao.getId());
            this.setUpdateWrapper(storeOutsideDao, wrapper);
        }
        if (storeOutsideDao.getContainerCode() != null) {
            wrapper.eq(StoreOutsideDao::getContainerCode, storeOutsideDao.getContainerCode());
            this.setUpdateWrapper(storeOutsideDao, wrapper);
        }
        return baseMapper.update(null, wrapper) > 0;
    }


    public void setUpdateWrapper(StoreOutsideDao storeOutsideDao, LambdaUpdateWrapper<StoreOutsideDao> wrapper) {
        wrapper.set(StoreOutsideDao::getUpdateDate, new Date());
        if (storeOutsideDao.getStatus() != null) {
            wrapper.set(StoreOutsideDao::getStatus, storeOutsideDao.getStatus());
            if (storeOutsideDao.getStatus().equals(InboundStatusEnum.STORAGE_FREE.status)) {
                wrapper.set(StoreOutsideDao::getContainerCode, null);
            }
            if (storeOutsideDao.getStatus().equals(InboundStatusEnum.STORAGE_LOAD.status)) {
                wrapper.set(StoreOutsideDao::getContainerCode, storeOutsideDao.getContainerCode());
            }
        }
        if (storeOutsideDao.getIsLock() != null) {
            wrapper.set(StoreOutsideDao::getIsLock, storeOutsideDao.getIsLock());
        }
        if (storeOutsideDao.getWareType() != null) {
            wrapper.set(StoreOutsideDao::getWareType, storeOutsideDao.getWareType());
        }
    }

    @Override
    public void download(List<StoreOutsideDao> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (StoreOutsideDao outsideDao : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("储位名称", outsideDao.getStoreName());
            map.put("储位类型", outsideDao.getStoreType());
            map.put("位置", outsideDao.getFloor());
            map.put("区域号", outsideDao.getRegion());
            map.put("层数号", outsideDao.getFrame());
            map.put("储位号", outsideDao.getSerial());
            map.put("库区类型", outsideDao.getWareType());
            map.put("货位类型", outsideDao.getGoodType());
            map.put("载具码", outsideDao.getContainerCode());
            map.put("储位状态", outsideDao.getStatus());
            map.put("是否锁定", outsideDao.getIsLock());
            map.put("创建时间", outsideDao.getCreateDate());
            map.put("更新时间", outsideDao.getUpdateDate());
            map.put("储位重量", outsideDao.getWeight());
            map.put("储位长", outsideDao.getSLong());
            map.put("储位宽", outsideDao.getSWide());
            map.put("储位高", outsideDao.getSTall());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }


    /**
     *
     * @param name 储位名称
     * @param workIp 工作站IP
     * @param floor 楼层
     * @param goodType 货物类型
     * @param storeIdList 可用储位ID列表
     */
    @Override
    public void findAvailableStoreIdList(String name, String workIp, String floor,
                                         String goodType, List<String> storeIdList) {
        if (goodType.equals(ConstantStatus.SORTING_AREA)) {
            storeIdList.addAll(this.findAvailableStoreId(name, floor, workIp, ConstantStatus.SORTING_AREA));
        }
        if (goodType.equals(ConstantStatus.PICKING_AREA)) {
            storeIdList.addAll(this.findAvailableStoreId(floor, ConstantStatus.PICKING_AREA));
        }
    }

}




